﻿using DongFangGuoKai.WMS.IApiService;
using DongFangGuoKai.WMSPlatform.Core;
using DongFangGuoKai.WMSPlatform.Domain.AGVModels;
using DongFangGuoKai.WMSPlatform.Domain.Enums;
using DongFangGuoKai.WMSPlatform.Domain.Models;
using DongFangGuoKai.WMSPlatform.Domain.WCSModels;
using DongFangGuoKai.WMSPlatform.Service.OutboundOrderDetail.DTO;
using DongFangGuoKai.WMSPlatform.Service.InboundOrderDetail.DTO;
using System.Diagnostics;
using System.Transactions;

namespace DongFangGuoKai.WMSPlatform.Service.OutboundOrderDetail
{
    public class TOutboundOrderDetailService : ITOutboundOrderDetailService
    {
        protected readonly static object _lockObj = new object();
        private readonly Repository<t_ShippingOrderDetail> shippingOrderDetailrepost;
        private readonly Repository<t_ShippingLockCell> shippingLockCellrepost;
        private readonly Repository<t_Inventory> inventoryrepost;
        private readonly Repository<t_Cell> cellrepost;
        private readonly Repository<t_StackingStorage> stackingstoragerepost;
        private readonly Repository<t_InventoryLog> inventorylogrepost;
        private readonly Repository<t_ReceivingBill> receivingbinllrepost;
        private readonly Repository<t_ReceivingBillDetail> receivingbilldetailrepost;
        private readonly Repository<t_ReceivingOrderDetail> receivingOrderDetailrepost;
        private readonly Repository<t_Instruct> instructrepost;
        private readonly IAGVService aGVService;
        private readonly Repository<t_PickingOrder> pinckingorderrepost;
        private readonly Repository<t_InventoryDetail> inventoryDetailrepost;
        private readonly Repository<t_Pallet> palletrepost;

        public TOutboundOrderDetailService(
              Repository<t_ShippingOrderDetail> shippingOrderDetailrepost,
              IAGVService aGVService
             
            )
        {
            this.shippingOrderDetailrepost = shippingOrderDetailrepost;
            shippingLockCellrepost = shippingOrderDetailrepost.ChangeRepository<Repository<t_ShippingLockCell>>();
            inventoryrepost = shippingOrderDetailrepost.ChangeRepository<Repository<t_Inventory>>();
            cellrepost = shippingOrderDetailrepost.ChangeRepository<Repository<t_Cell>>();
            stackingstoragerepost = shippingOrderDetailrepost.ChangeRepository<Repository<t_StackingStorage>>();
            inventorylogrepost = shippingOrderDetailrepost.ChangeRepository<Repository<t_InventoryLog>>();
            receivingbinllrepost = shippingOrderDetailrepost.ChangeRepository<Repository<t_ReceivingBill>>();
            receivingbilldetailrepost = shippingOrderDetailrepost.ChangeRepository<Repository<t_ReceivingBillDetail>>();
            receivingOrderDetailrepost = shippingOrderDetailrepost.ChangeRepository<Repository<t_ReceivingOrderDetail>>();
            instructrepost = shippingOrderDetailrepost.ChangeRepository<Repository<t_Instruct>>();
            pinckingorderrepost = shippingOrderDetailrepost.ChangeRepository<Repository<t_PickingOrder>>();

            inventoryDetailrepost = shippingOrderDetailrepost.ChangeRepository<Repository<t_InventoryDetail>>();
            palletrepost = shippingOrderDetailrepost.ChangeRepository<Repository<t_Pallet>>();

            this.aGVService = aGVService;
        }

        /// <summary>
        /// 添加出库单
        /// </summary>
        /// <param name="addOutBoundOrder"></param>
        public bool AddOutboundOrders(AddOutBoundOrder addOutBoundOrder, out string errorMag)
        {
            errorMag = "";
            try
            {
                shippingOrderDetailrepost.AsTenant().BeginTran();
                var rece = shippingOrderDetailrepost.GetFirst(r => r.OutBoundNo == addOutBoundOrder.OutBoundNo);
                if (rece != null)
                {
                    shippingOrderDetailrepost.AsTenant().RollbackTran();
                    errorMag = "有相同的出库单号";
                    return false;
                }

                //查询下传的出库单委托单是否存在
                var receivingObj = receivingbinllrepost.GetList(r => r.BillNO == addOutBoundOrder.OrderNo);
                if (receivingObj == null)
                {
                    shippingOrderDetailrepost.AsTenant().RollbackTran();
                    errorMag = "未查询到委托单";
                    return false;
                }

                if (addOutBoundOrder.SampleInfo is null || addOutBoundOrder.SampleInfo.Count <= 0)
                {
                    shippingOrderDetailrepost.AsTenant().RollbackTran();
                    errorMag = "SampleInfo集合为空";
                    return false;
                }
                t_ShippingOrderDetail shippingOrder = new t_ShippingOrderDetail();
                shippingOrder.CreateDate = DateTime.Now;
                shippingOrder.OrderSN = addOutBoundOrder.OrderNo;
                shippingOrder.Status = 0;
                shippingOrder.OutBoundNo = addOutBoundOrder.OutBoundNo;


                if (shippingOrderDetailrepost.Insert(shippingOrder) == false)
                {
                    shippingOrderDetailrepost.AsTenant().RollbackTran();
                    errorMag = "添加出库委托单失败";
                    return false;
                }
                List<t_ShippingLockCell> shippinglockcells = new List<t_ShippingLockCell>();
                foreach (var item in addOutBoundOrder.SampleInfo)
                {
                    var receivingDetailObj = receivingbilldetailrepost.GetFirst(r => r.BillNO == addOutBoundOrder.OrderNo && r.MaterialCode == item.SampleCode);
                    if (receivingDetailObj == null)
                    {
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        errorMag = "委托单未查询到样品信息";
                        return false;
                    }
                    t_ShippingLockCell shippinglockcell = new t_ShippingLockCell();
                    shippinglockcell.OrderId = shippingOrder.Id;
                    shippinglockcell.MaterialId = item.SampleId;
                    shippinglockcell.MaterialCode = item.SampleCode;
                    shippinglockcell.MaterialName = item.SamplelName;
                    shippinglockcell.OutQty = item.SampleNum.GetValueOrDefault();
                    shippinglockcell.WindowCode = item.WindowCode;
                    shippinglockcell.CustomerName = item.CustomerName;
                    shippinglockcell.CustomerPhone = item.CustomerPhone;
                    shippinglockcells.Add(shippinglockcell);
                }
                if (shippingLockCellrepost.InsertRange(shippinglockcells) == false)
                {
                    shippingOrderDetailrepost.AsTenant().RollbackTran();
                    errorMag = "添加出库委托单明细失败";
                    return false;
                }
                var IsOK = ExecuteOutBound(addOutBoundOrder.OutBoundNo,  out errorMag);
                if (!IsOK)
                {
                    shippingOrderDetailrepost.AsTenant().RollbackTran();
                    errorMag = "出库失败" + errorMag;
                    return false;
                }
                shippingOrderDetailrepost.AsTenant().CommitTran();
                errorMag = "添加出库委托单成功";
                return true;
            }
            catch (Exception ex)
            {
                shippingOrderDetailrepost.AsTenant().RollbackTran();
                errorMag = "添加出库委托单失败：" + ex.Message;
                return false;
                throw;
            }
        }

        /// <summary>
        /// 执行出库
        /// </summary>
        /// <param name="OrdersNo"></param>
        /// <returns></returns>
        public bool ExecuteOutBound(string OutBoundNo, out string errorMsg)
        {
            errorMsg = string.Empty;
            lock (_lockObj)
            {
                try
                {
                    var shippingorder = shippingOrderDetailrepost.GetFirst(s => s.OutBoundNo == OutBoundNo);
                    if (shippingorder == null)
                    {
                        errorMsg = "未查询到出库委托单";
                        return false;
                    }
                   
                    var shippinglockcells = shippingLockCellrepost.GetList(s => s.OrderId == shippingorder.Id);
                    if (shippinglockcells is null || shippinglockcells.Count() <= 0)
                    {
                        errorMsg = "出库单明细不存在";
                        return false;
                    }
                    //查询要出库的样品
                    var inventorys = inventoryrepost.GetList().Where(i=>i.Status ==1 && shippinglockcells.Any(s=>s.MaterialCode == i.MaterialCode)).ToList();


                    //根据出库单的委托单号和出库单明细去组垛表中查询要出的数据
                    //var stackings = stackingstoragerepost.GetList(s => s.OrderNo == shippingorder.OrderSn).Where(s => shippinglockcells.Any(c => c.MaterialCode == s.MaterialCode)).ToList();
                    //if (stackings is null || stackings.Count() <= 0)
                    //{
                    //    errorMsg = "无组垛信息";
                    //    trans.Dispose();
                    //    return false;
                    //}
                    ////执行查出要出的库存物料
                    //var inventorys = inventoryrepost.GetList().Where(i => stackings.Any(s => s.Id == i.StackingStorageId) && i.Status == 1).ToList();
                    if (inventorys is null || inventorys.Count() <= 0)
                    {
                        errorMsg = "未查询到库存记录";
                        return false;
                    }
                    foreach (var inventory in inventorys)
                    {
                        inventory.Status = 4;
                        if (!inventoryrepost.Update(inventory))
                        {
                            errorMsg = "修改库存状态失败";
                            return false;
                        }
                    }
                    //因为出库物料有可能在一个仓位所有根据仓位进行去重
                    inventorys = inventorys.DistinctBy(i => i.LocationCode).ToList();
                    if (inventorys is null || inventorys.Count() <= 0)
                    {
                        errorMsg = "未查询到库存记录";
                        return false;
                    }

                    foreach (var item in inventorys)
                    {
                        //查询组垛表是因为需要组垛code
                        //var stacking = stackingstoragerepost.Get(s => s.Id == item.StackingStorageId);
                        //if (stacking is null)
                        //{
                        //    errorMsg = "未查询到组垛信息";
                        //    trans.Dispose();
                        //    return false;
                        //}
                        //var orderDetail = receivingOrderDetailrepost.Get(r => r.Id == item.RelatedOrderDetailId);

                        //寻找终点位置 ，如果后面输送线用上就不用寻找终点了
                        //int[] columnNos = new int[4] { 5, 6, 7, 8 }; //寻找出库位置的列

                        //var Outcell = cellrepost.Get(s=>s.AreaCode == "D01" && s.LineNo == 1 && s.LayerNo <= 4 && columnNos.Contains(s.ColumnNo) && s.Status == 1 && s.IsLock == false && s.FullStatus == 0);

                        //if (Outcell == null)
                        //{
                        //    errorMsg = "没有可出库的位置";
                        //    return false;
                        //}

                        //Outcell.BusinessType = EmBusinessType.Out;
                        //Outcell.Status = 2;
                        //Outcell.IsLock = true;
                        //Outcell.FullStatus = 1;
                        //Outcell.ModifyDate = DateTime.Now;

                        //if (!cellrepost.Update(Outcell))
                        //{
                        //    errorMsg = "修改仓位失败";
                        //    return false;
                        //}
                        
                        //生成指令
                        var instruct = new t_Instruct
                        {
                            //WarehouseCode = stackingstorage.WarehouseCode,
                            Status = 2,
                            ToLocation = "",
                            //StackingStorageId = stackingStorageId,//换成code
                            //StackingStorageCode = stacking.Code,
                            WorkDeviceType = EmWorkDeviceType.AGV,
                            InstructType = EmInstructType.Out,
                            Action = EmDeviceAction.Transport,
                            //RelatedOrderDetailId = orderDetail.Id,//换成code
                            RelatedOrderDetailCode = shippingorder.OutBoundNo,
                            DeviceCode = "",
                            FromLocation = item.ERPLocationCode,
                            //ExpectedToLocation = Outcell.Code, //这个写成终点的仓位code
                            LogicalCellAddr = "S00001S1501013",//Outcell.Erpcode,  // 输送线终点
                            InstructIndex = 1,
                            PalletBarcode = item.PalletBarcode,
                            ScanedBarcode = item.PalletBarcode,
                            Priority = 9999,
                            //Qty = materialNum.GetValueOrDefault(),
                            FinishedQTY = 0,
                            StartTime = DateTime.Now,
                            BusinessGroupId = Guid.NewGuid(),
                            BusinessType = (int)EmBusinessType.Out,
                            //BillType = (int)orderDetail.BillType.GetValueOrDefault(),

                        };
                        if (instructrepost.Insert(instruct) == false)
                        {
                            errorMsg = "指令保存失败";
                            return false;
                        }

                        // 发送指令
                        var result = AGVTest(instruct, out errorMsg);
                        if (!result)
                        {
                            errorMsg = "avg返回结果：" + errorMsg;
                            return false;
                        }

                    }
                    errorMsg = "提交成功";
                    return true;
                }
                catch (Exception ex)
                {
                    errorMsg = "出库失败" + ex.Message;
                    return false;
                    throw;
                }
            }
        }

        /// <summary>
        /// 完成出库托盘到窗口后wms告诉我完成出库
        /// </summary>
        /// <param name="instruct"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        public bool CompleteOutBound(ConveyorLineOverModel conveyorLineOver, out string errorMsg)
        {
            errorMsg = "";
            if (string.IsNullOrEmpty(conveyorLineOver.OutBoundNo) || string.IsNullOrEmpty(conveyorLineOver.BarCode))
            {
                errorMsg = "参数错误";
                return false;
            }
            lock (_lockObj)
            {
                try
                {
                    shippingOrderDetailrepost.AsTenant().BeginTran();
                    var outorderDetail = shippingOrderDetailrepost.GetFirst(r => r.OutBoundNo == conveyorLineOver.OutBoundNo);
                    if (outorderDetail is null)
                    {
                        errorMsg = "出库单信息未找到";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }

                    //查询出本次指令出库的样品
                    var inventoryList = inventoryrepost.GetList(i=>i.PalletBarcode == conveyorLineOver.BarCode && i.Status == 9);
                    if (inventoryList.Count() <= 0)
                    {
                        errorMsg = "未找到库存";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }
                    foreach (var inventoryobj in inventoryList)
                    {
                        #region 修改和删除信息
                        var stacking = stackingstoragerepost.GetFirst(s => s.Id == inventoryobj.StackingStorageId);
                        if (stacking == null)
                        {
                            errorMsg = "无组垛信息";
                            shippingOrderDetailrepost.AsTenant().RollbackTran();
                            return false;
                        }
                        stacking.Status = 0;
                        stacking.ModifyDate = DateTime.Now;
                        if (!stackingstoragerepost.Update(stacking))
                        {
                            errorMsg = "组垛数据状态修改失败";
                            shippingOrderDetailrepost.AsTenant().RollbackTran();
                            return false;
                        }
                        
                        var inventorydetail = inventoryDetailrepost.GetFirst(i => i.InventoryId == inventoryobj.Id);

                        if (inventorydetail is null)
                        {
                            errorMsg = "未找到库存明细";
                            shippingOrderDetailrepost.AsTenant().RollbackTran();
                            return false;
                        }
                        if (!inventoryrepost.Delete(inventoryobj))
                        {
                            errorMsg = "库存删除失败";
                            shippingOrderDetailrepost.AsTenant().RollbackTran();
                            return false;
                        }
                        if (!inventoryDetailrepost.Delete(inventorydetail))
                        {
                            errorMsg = "库存明细删除失败";
                            shippingOrderDetailrepost.AsTenant().RollbackTran();
                            return false;
                        }

                        #endregion

                        //保存库存日志表
                        var inventorylog = new t_InventoryLog
                        {
                            SourceType = 20,
                            SourceSN = outorderDetail.OutBoundNo,
                            WarehouseId = inventoryobj.WarehouseId,
                            WarehouseName = inventoryobj.WarehouseName,
                            AreaName = inventoryobj.AreaName,
                            AreaId = inventoryobj.AreaId,
                            LocationCode = inventoryobj.LocationCode,
                            PalletBarcode = inventoryobj.PalletBarcode,
                            OwnerId = inventoryobj.OwnerId,
                            OwnerName = inventoryobj.OwnerName,
                            MaterialId = stacking.MaterialId,
                            MaterialName = stacking.MaterialName,
                            //BatchNo = inventory.BatchNO,
                            //StartQTY = instruct.QTY,
                            //ChangeQTY = -instruct.QTY.GetValueOrDefault(),
                            //EndQTY = 0,
                            BaseUnitId = inventoryobj.UnitId,
                            BaseUnitName = inventoryobj.UnitName,
                            CreateDate = DateTime.Now,
                        };
                        if (inventorylogrepost.Insert(inventorylog) == false)
                        {
                            errorMsg = "库存日志表保存失败";
                            shippingOrderDetailrepost.AsTenant().RollbackTran();
                            return false;
                        }
                    }

                    //修改仓位的信息状态
                    var cell = cellrepost.GetFirst(c => c.Code == inventoryList[0].LocationCode);
                    if (cell is null)
                    {
                        errorMsg = "原仓位查询有误";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }
                    cell.IsLock = false;
                    cell.BusinessType = 0;
                    cell.FullStatus = 0;
                    cell.Status = 1;
                    cell.ModifyDate = DateTime.Now;
                    if (!cellrepost.Update(cell))
                    {
                        errorMsg = "修改库存仓位失败";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }

                    //修改托盘的信息状态
                    var pall = palletrepost.GetFirst(p => p.PalletBarcode == conveyorLineOver.BarCode);
                    if (pall is null)
                    {
                        errorMsg = "托盘查询有误！";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }
                    pall.LocationCode = "";
                    pall.LocationName = "";
                    pall.ERPLocationName = "";
                    pall.ModifyDate = DateTime.Now;
                    if (!palletrepost.Update(pall))
                    {
                        errorMsg = "托盘货位信息解绑失败";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }

                    /* 查询终点位置 现在不用了 ，往输送线上放箱子就不用了
                    var outcell = cellrepost.Get(c=>c.Code == instruct.ExpectedToLocation);

                    if (outcell is null)
                    {
                        errorMsg = "目标仓位查询有误！";
                        trans.Dispose();
                        return false;
                    }
                    outcell.IsLock = false;
                    outcell.BusinessType = 0;
                    outcell.FullStatus = 0;
                    outcell.Status = 1;
                    outcell.ModifyDate = DateTime.Now;
                    if (!cellrepost.Update(outcell))
                    {
                        errorMsg = "修改目标仓位状态失败！";
                        trans.Dispose();
                        return false;
                    }
                    
                    //解绑 AGV仓位 后期输送线有了就不用解绑了
                    (string avgPalletType, string avgTaskType) = SwitchType(pall.Type.GetValueOrDefault());
                    if (string.IsNullOrEmpty(avgPalletType))
                    {
                        errorMsg = "转换AGV容器类型失败";
                        return false;
                    }
                    BindCtnrAndBinModel bindCtnrAndBinModel = new BindCtnrAndBinModel();
                    var uuid = Guid.NewGuid();
                    bindCtnrAndBinModel.reqCode = uuid.ToString("N");
                    bindCtnrAndBinModel.taskCode = bindCtnrAndBinModel.reqCode;
                    bindCtnrAndBinModel.reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

                    //解绑用户
                    bindCtnrAndBinModel.clientCode = "PDA";
                    //解绑容器类型 大容器类型
                    bindCtnrAndBinModel.ctnrTyp = avgPalletType;
                    //banging起始目标储位  
                    bindCtnrAndBinModel.stgBinCode = instruct.LogicalCellAddr;
                    //解绑
                    bindCtnrAndBinModel.indBind = "0";

                    var res = aGVService.BindCntrAndUnBindTask(bindCtnrAndBinModel);
                    if (res.code != "0")
                    {
                        errorMsg = "AVG绑定失败：" + res.message;
                        return false;
                    }
                    */

                    errorMsg = "提交成功";
                    shippingOrderDetailrepost.AsTenant().CommitTran();
                    return true;
                }
                catch (Exception ex)
                {
                    shippingOrderDetailrepost.AsTenant().RollbackTran();
                    errorMsg = "错误信息：" + ex.Message;
                    return false;
                    throw;
                }
            }
        }

        /// <summary>
        /// avg调用完成出库
        /// </summary>
        /// <param name="instruct"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        public bool CompleteOutBound(t_Instruct instruct, out string errorMsg)
        {
            errorMsg = "";
            if (string.IsNullOrEmpty(instruct.PalletBarcode) || string.IsNullOrEmpty(instruct.RelatedOrderDetailCode))
            {
                errorMsg = "参数错误";
                return false;
            }
            lock (_lockObj)
            {
                try
                {
                    shippingOrderDetailrepost.AsTenant().BeginTran();
                    var outorderDetail = shippingOrderDetailrepost.GetFirst(r => r.OutBoundNo == instruct.RelatedOrderDetailCode);
                    if (outorderDetail is null)
                    {
                        errorMsg = "出库单信息未找到";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }

                    //查询出本次指令出库的样品
                    var inventoryList = inventoryrepost.GetList(i => i.PalletBarcode == instruct.PalletBarcode && i.Status == 9);
                    if (inventoryList.Count() <= 0)
                    {
                        errorMsg = "未找到库存";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }
                    foreach (var inventoryobj in inventoryList)
                    {
                        #region 修改和删除信息
                        var stacking = stackingstoragerepost.GetFirst(s => s.Id == inventoryobj.StackingStorageId);
                        if (stacking == null)
                        {
                            errorMsg = "无组垛信息";
                            shippingOrderDetailrepost.AsTenant().RollbackTran();
                            return false;
                        }
                        stacking.Status = 0;
                        stacking.ModifyDate = DateTime.Now;
                        if (!stackingstoragerepost.Update(stacking))
                        {
                            errorMsg = "组垛数据状态修改失败";
                            shippingOrderDetailrepost.AsTenant().RollbackTran();
                            return false;
                        }

                        var inventorydetail = inventoryDetailrepost.GetFirst(i => i.InventoryId == inventoryobj.Id);

                        if (inventorydetail is null)
                        {
                            errorMsg = "未找到库存明细";
                            shippingOrderDetailrepost.AsTenant().RollbackTran();
                            return false;
                        }
                        if (!inventoryrepost.Delete(inventoryobj))
                        {
                            errorMsg = "库存删除失败";
                            shippingOrderDetailrepost.AsTenant().RollbackTran();
                            return false;
                        }
                        if (!inventoryDetailrepost.Delete(inventorydetail))
                        {
                            errorMsg = "库存明细删除失败";
                            shippingOrderDetailrepost.AsTenant().RollbackTran();
                            return false;
                        }

                        #endregion

                        //保存库存日志表
                        var inventorylog = new t_InventoryLog
                        {
                            SourceType = 20,
                            SourceSN = outorderDetail.OutBoundNo,
                            WarehouseId = inventoryobj.WarehouseId,
                            WarehouseName = inventoryobj.WarehouseName,
                            AreaName = inventoryobj.AreaName,
                            AreaId = inventoryobj.AreaId,
                            LocationCode = inventoryobj.LocationCode,
                            PalletBarcode = inventoryobj.PalletBarcode,
                            OwnerId = inventoryobj.OwnerId,
                            OwnerName = inventoryobj.OwnerName,
                            MaterialId = stacking.MaterialId,
                            MaterialName = stacking.MaterialName,
                            //BatchNo = inventory.BatchNO,
                            //StartQTY = instruct.QTY,
                            //ChangeQTY = -instruct.QTY.GetValueOrDefault(),
                            //EndQTY = 0,
                            BaseUnitId = inventoryobj.UnitId,
                            BaseUnitName = inventoryobj.UnitName,
                            CreateDate = DateTime.Now,
                        };
                        if (!inventorylogrepost.Insert(inventorylog))
                        {
                            errorMsg = "库存日志表保存失败";
                            shippingOrderDetailrepost.AsTenant().RollbackTran();
                            return false;
                        }
                    }

                    //修改仓位的信息状态
                    var cell = cellrepost.GetFirst(c => c.Code == inventoryList[0].LocationCode);
                    if (cell is null)
                    {
                        errorMsg = "原仓位查询有误";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }
                    cell.IsLock = false;
                    cell.BusinessType = 0;
                    cell.FullStatus = 0;
                    cell.Status = 1;
                    cell.ModifyDate = DateTime.Now;
                    if (!cellrepost.Update(cell))
                    {
                        errorMsg = "修改库存仓位失败";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }

                    //修改托盘的信息状态
                    var pall = palletrepost.GetFirst(p => p.PalletBarcode == instruct.PalletBarcode);
                    if (pall is null)
                    {
                        errorMsg = "托盘查询有误！";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }
                    pall.LocationCode = "";
                    pall.LocationName = "";
                    pall.ERPLocationName = "";
                    pall.ModifyDate = DateTime.Now;
                    if (!palletrepost.Update(pall))
                    {
                        errorMsg = "托盘货位信息解绑失败";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }

                    // 查询终点位置 现在不用了 ，往输送线上放箱子就不用了
                    var outcell = cellrepost.GetFirst(c=>c.Code == instruct.ExpectedToLocation);

                    if (outcell is null)
                    {
                        errorMsg = "目标仓位查询有误！";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }
                    outcell.IsLock = false;
                    outcell.BusinessType = 0;
                    outcell.FullStatus = 0;
                    outcell.Status = 1;
                    outcell.ModifyDate = DateTime.Now;
                    if (!cellrepost.Update(outcell))
                    {
                        errorMsg = "修改目标仓位状态失败！";
                        shippingOrderDetailrepost.AsTenant().RollbackTran();
                        return false;
                    }
                    
                    //解绑 AGV仓位 后期输送线有了就不用解绑了
                    (string avgPalletType, string avgTaskType) = SwitchType(pall.Type.GetValueOrDefault());
                    if (string.IsNullOrEmpty(avgPalletType))
                    {
                        errorMsg = "转换AGV容器类型失败";
                        return false;
                    }
                    BindCtnrAndBinModel bindCtnrAndBinModel = new BindCtnrAndBinModel();
                    var uuid = Guid.NewGuid();
                    bindCtnrAndBinModel.reqCode = uuid.ToString("N");
                    bindCtnrAndBinModel.taskCode = bindCtnrAndBinModel.reqCode;
                    bindCtnrAndBinModel.reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

                    //解绑用户
                    bindCtnrAndBinModel.clientCode = "PDA";
                    //解绑容器类型 大容器类型
                    bindCtnrAndBinModel.ctnrTyp = avgPalletType;
                    //banging起始目标储位  
                    bindCtnrAndBinModel.stgBinCode = instruct.LogicalCellAddr;
                    //解绑
                    bindCtnrAndBinModel.indBind = "0";

                    var res = aGVService.BindCntrAndUnBindTask(bindCtnrAndBinModel);
                    if (res.code != "0")
                    {
                        errorMsg = "AVG绑定失败：" + res.message;
                        return false;
                    }
                    

                    errorMsg = "提交成功";
                    shippingOrderDetailrepost.AsTenant().CommitTran();
                    return true;
                }
                catch (Exception ex)
                {
                    shippingOrderDetailrepost.AsTenant().RollbackTran();
                    errorMsg = "错误信息：" + ex.Message;
                    return false;
                    throw;
                }
            }
        }

        /// <summary>
        /// 出库样品箱号到输送线
        /// </summary>
        /// <param name="instruct"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        public bool SampleToConveyor(t_Instruct instruct, out string errorMsg)
        {
            errorMsg = "";
            if (string.IsNullOrEmpty(instruct.PalletBarcode))
            {
                errorMsg = "参数错误";
                return false;
            }
            lock (_lockObj)
            {
                using var trans = new TransactionScope();
                try
                {
                    var inst = instructrepost.GetFirst(i => i.Id == instruct.Id);
                    if (inst == null)
                    {
                        trans.Dispose();
                        errorMsg = "未找到指令";
                        return false;
                    }

                    inst.Status = 4;
                    if (!instructrepost.Update(inst))
                    {
                        errorMsg = "修改指令失败";
                        trans.Dispose();
                        return false;
                    }

                    //查询出本次指令出库的样品
                    var inventoryList = inventoryrepost.GetList(i => i.PalletBarcode == instruct.PalletBarcode && i.Status == 4);
                    if (inventoryList.Count() <= 0)
                    {
                        errorMsg = "未找到库存";
                        trans.Dispose();
                        return false;
                    }
                    foreach (var inventoryobj in inventoryList)
                    {
                        inventoryobj.Status = 9;
                        if (!inventoryrepost.Update(inventoryobj))
                        {
                            trans.Dispose();
                            errorMsg = "修改库存状态失败";
                            return false;
                        }
                    }

                    errorMsg = "提交成功";
                    trans.Complete();
                    return true;
                }
                catch (Exception ex)
                {
                    trans.Dispose();
                    errorMsg = "错误信息：" + ex.Message;
                    return false;
                    throw;
                }
            }
        }


        /// <summary>
        /// 调用avg
        /// </summary>
        /// <param name="instruct"></param>
        /// <param name="errMsg"></param>
        /// <returns></returns>
        private bool AGVTest(t_Instruct instruct, out string errMsg)
        {
            errMsg = string.Empty;

            if (instruct == null)
            {
                errMsg = "指令为空！";
                return false;
            }
            var pall = palletrepost.GetFirst(p => p.PalletBarcode == instruct.PalletBarcode);
            if (pall is null)
            {
                errMsg = "未查询出箱号和托盘！" + instruct.PalletBarcode;
                return false;
            }
            if (pall.Type == null)
            {
                errMsg = "托盘类型为空！";
                return false;
            }
            (string avgPalletType, string avgTaskType) = SwitchType(pall.Type.GetValueOrDefault());
            if (string.IsNullOrEmpty(avgPalletType))
            {
                errMsg = "转换AGV容器类型失败";
                return false;
            }
            //return true;
            

            //添加任务单
            AddTaskModel addTaskModel = new AddTaskModel();
            addTaskModel.reqCode = Guid.NewGuid().ToString("N");
            addTaskModel.clientCode = "PDA";
            //ARM入库出库
            addTaskModel.TaskTyp = "A12";
           
            //叉车对应的大容器类型
            addTaskModel.CtnrTyp = avgPalletType;
            addTaskModel.taskCode = instruct.BusinessGroupId.ToString();

            //任务起始点仓位编码
            addTaskModel.PositionCodePath = new PositionCodePathDto[2] {
                    new PositionCodePathDto() {
                        //叉车实际位置
                        PositionCode=instruct.FromLocation,// 起始地址 D00080A2502013
                        Type="05"//固定05
                    },
                    //实际传入编号，测试传入仓位
                    new PositionCodePathDto() {
                        PositionCode=instruct.LogicalCellAddr,//ERP目标地址
                        Type="05"
                    }
                };

            var res2 = aGVService.CreateTask(addTaskModel);
            if (res2.code != "0")
            {
                errMsg = "AVG：" + res2.message;
                return false;
            }

            return true;

        }

        /// <summary>
        /// 把WMS的容器类型转换为AGV的容器类型
        /// </summary>
        /// <param name="wmsType"></param>
        /// <returns></returns>
        private (string, string) SwitchType(int wmsType)
        {
            switch (wmsType)
            {
                case 0:
                    return ("3", "B1");
                case 1:
                    return ("2", "A11");
                case 2:
                    return ("1", "A10");
                default:
                    return (null, null);
            }
        }
    }
}
